

#include "i7816_hal_con_raw_define.h"
#include <stdint.h>
#include "i7816_define.h"
#include "i7816_hal.h"

/*======================================接口操作===============================================*/
/// @brief 选择对应的卡槽
/// @param hw 接口资源指针
/// @return I7816_S_OK
i7816_status_t i7816_hal_select(i7816_hw_t* hw){
    return I7816_S_OK;
}

static void i7816_hal_afio_deactivate(const AFIO_T* afio){
    IO_Set(&afio->io, 0);
    IO_Config(&afio->io, IO_Mode_OUT);
}


void i7816_hal_deactive(i7816_hw_t* hw){
    const i7816_con_raw_t* con = hw->con;
    IO_Set(&con->reset, 0);
    i7816_hal_delay_ms(1);
    i7816_hal_afio_deactivate(&con->clock);
	//设置为输入上拉，若设置为输出，可能导致电平冲突
//	    i7816_hal_afio_deactivate(&con->io);
    IO_Init(&con->io.io, IO_Mode_IPU);
    i7816_hal_delay_ms(1);
    IO_Set(&con->vcc, 0);
}

i7816_status_t i7816_hal_activate(i7816_hw_t* hw, i7816_class_t type){
    const i7816_con_raw_t* con = hw->con;
    IO_Set(&con->vcc, 1);
    i7816_hal_delay_ms(1);
    IO_AF_Set(&con->io.io, con->io.af);
    IO_Init(&con->io.io, IO_Mode_AFOD);
    i7816_hal_delay_ms(1);
    AFIO_Init(&con->clock);
    i7816_hal_delay_ms(1);
    IO_Set(&con->reset, 1);
    return I7816_S_OK;
}

static i7816_status_t i7816_hal_cold_reset(i7816_hw_t* hw, i7816_class_t type, int hold_ms){
    i7816_hal_deactive(hw);
    i7816_hal_delay_ms(hold_ms);
    return i7816_hal_activate(hw, type);
}

static i7816_status_t i7816_hal_warm_reset(i7816_hw_t* hw, i7816_class_t type, int hold_ms){
    const i7816_con_raw_t* con = hw->con;
    IO_Set(&con->reset, 0);
    i7816_hal_delay_ms(hold_ms);
    IO_Set(&con->reset, 1);
    return I7816_S_OK;
}

i7816_status_t i7816_hal_reset(i7816_hw_t* hw, i7816_class_t type, reset_mode_t mode){
    if(mode == RESET_MODE_COLD){
        return i7816_hal_cold_reset(hw, type, 10);
    }
    else{
        return i7816_hal_warm_reset(hw, type, 1);
    }    
}

/// @brief 获取支持的电压等级。
/// @param hw 
/// @return ICC_CLASS_B（3V）
uint8_t i7816_hal_get_support_type(i7816_hw_t* hw){
    return (uint8_t)ICC_CLASS_B;
}

static void con_raw_init(const i7816_con_raw_t* con){    
    IO_Init(&con->vcc, IO_Mode_OUT);
    IO_Set(&con->vcc, 0);

    IO_Init(&con->reset, IO_Mode_OUT);
    IO_Set(&con->reset, 0);

//	    IO_AF_Set(&con->io.io, con->io.af);
    IO_Init(&con->io.io, IO_Mode_IPU);

    IO_Set(&con->clock.io, 0);
    IO_Init(&con->clock.io, IO_Mode_OUT);
}

void i7816_hal_connect_init(i7816_hw_t* hw){
    const i7816_con_raw_t* con = hw->con;
    con_raw_init(con);
}

bool i7816_hal_check_present(i7816_hw_t* hw){
    return true;
}

